package com.javaDemo.ti;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Exchanger {
    static class Producer extends Thread {
        private java.util.concurrent.Exchanger<Integer> exchanger;
        private static int data = 0;
        Producer(String name, java.util.concurrent.Exchanger<Integer> exchanger) {
            super("Producer-" + name);
            this.exchanger = exchanger;
        }

        @Override
        public void run() {
            for (int i=1; i<5; i++) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    data = i;
                    System.out.println(getName()+" 交换前:" + data);
                    data = exchanger.exchange(data);
                    System.out.println(getName()+" 交换后:" + data);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Consumer extends Thread {
        private java.util.concurrent.Exchanger<Integer> exchanger;
        private static int data = 0;
        Consumer(String name, java.util.concurrent.Exchanger<Integer> exchanger) {
            super("Consumer-" + name);
            this.exchanger = exchanger;
        }

        @Override
        public void run() {
            while (true) {
                data = 0;
                System.out.println(getName()+" 交换前:" + data);
                try {
                    TimeUnit.SECONDS.sleep(1);
                    data = exchanger.exchange(data);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(getName()+" 交换后:" + data);
            }
        }
    }
    //
    // public static void main(String[] args) throws InterruptedException {
    //     Exchanger<Integer> Exchanger = new Exchanger<Integer>();
    //     new Producer("", Exchanger).start();
    //     new Consumer("", Exchanger).start();
    //     TimeUnit.SECONDS.sleep(7);
    //     System.exit(-1);
    // }


    public static void main(String[] args) {
        // ExecutorService executor = Executors.newCachedThreadPool();
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
        ExecutorService executor = new ThreadPoolExecutor(4,8,5L,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
        // ExecutorService pool = new ThreadPoolExecutor(5, 200,
        //         0L, TimeUnit.MILLISECONDS,
        //         new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
        //

        final java.util.concurrent.Exchanger exchanger = new java.util.concurrent.Exchanger();
        executor.execute(new Runnable() {
            String data1 = "克拉克森，小拉里南斯";
            @Override
            public void run() {
                nbaTrade(data1, exchanger);
            }
        });

        executor.execute(new Runnable() {
            String data1 = "格里芬";
            @Override
            public void run() {
                nbaTrade(data1, exchanger);
            }
        });

        executor.execute(new Runnable() {
            String data1 = "哈里斯";
            @Override
            public void run() {
                nbaTrade(data1, exchanger);
            }
        });

        executor.execute(new Runnable() {
            String data1 = "以赛亚托马斯，弗莱";
            @Override
            public void run() {
                nbaTrade(data1, exchanger);
            }
        });

        executor.shutdown();
    }

    private static void nbaTrade(String data1, java.util.concurrent.Exchanger exchanger) {
        try {
            System.out.println(Thread.currentThread().getName() + "在交易截止之前把 " + data1 + " 交易出去");
            Thread.sleep((long) (Math.random() * 1000));

            String data2 = (String) exchanger.exchange(data1);
            System.out.println(Thread.currentThread().getName() + "交易得到" + data2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}